package site.qjdb.controller;


import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import site.qjdb.constant.Info;
import site.qjdb.pojo.User;
import site.qjdb.pojo.response.CommonResult;
import site.qjdb.pojo.response.ResponseCode;
import site.qjdb.service.UserService;
import site.qjdb.util.CommonUtils;
import site.qjdb.util.MD5Utils;
import site.qjdb.util.VerifyCode;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

@Controller
@RequestMapping("/user")
public class UserController {
	@Resource
	private UserService userService;

	private final String DEFAULT_IMG_PATH = "/qb/images/face/default.jpg"; // 用户默认头像路径
	
	/**
	 * 	获得验证码图片
	 * 
	 */
	@RequestMapping("/getVI")
	public void getVI(HttpSession session, HttpServletResponse response) throws IOException {
		VerifyCode vc = new VerifyCode();
		BufferedImage bi = vc.getImage();
		String text = vc.getText();
		session.setAttribute("verifyCode", text);
		VerifyCode.output(bi, response.getOutputStream());
	}

	/**
	 * 	得到验证码文本内容
	 */
	@ResponseBody
	@RequestMapping("/getVC")
	public Object getVC(HttpSession session) {
		CommonResult<String> result = new CommonResult<>(ResponseCode.SUCCESS, "success",
				(String) session.getAttribute("verifyCode"));
		return result;
	}
	
	/**
	 * 	用户注册
	 * 	sno：学号，必传
	 * 	pwd：密码（已经过了MD5加密），必传
	 * 	verifyCode：验证码，必传
	 * 	cf：校验字段（前端动态生成一段字符串，必传。生成规则：
	 * 			1. 先在  qjdb 单词之间随机插入一个字符形成新的字符串str，例：q7db
	 * 			2. 再将字符串str用MD5算法加密，生成新的字符串newStr，最后将插入的位置和字符添加在newStr后面。
	 * 	pmr：此字段应为"",若不为空则认为是恶意注册，必传
	 * 	agreement：1表示同意了用户协议，必传
	 * 
	 */
	@ResponseBody
	@RequestMapping(value = "/regist", method = RequestMethod.POST)
	public Object regist(@RequestParam(value = "number") String sno,
			@RequestParam(value = "password") String pwd,
			@RequestParam String verifyCode,
			@RequestParam String cf,
			@RequestParam String pmr,
			@RequestParam String agreement,
			HttpSession session) {
		// 校验agreement
		if(!"1".equals(agreement)) {
			// 非法注册
			return new CommonResult<>(ResponseCode.ILLEGAL_REGIST);
		}
		// 校验pmr
		if(pmr != null && pmr.length() > 0) {
			// 非法注册
			return new CommonResult<>(ResponseCode.ILLEGAL_REGIST);
		}
		// 校验cf
		try {
			int index = Integer.parseInt(cf.substring(32, 33));
			String ele = new String(cf.substring(33, 34));
			List<String> list = new LinkedList<>();
			list.add("q");
			list.add("j");
			list.add("d");
			list.add("b");
			list.add(index, ele);
			cf = cf.substring(0, 32);
			if(!MD5Utils.md5(listToString(list)).equals(cf)) {
				// 非法注册
				return new CommonResult<>(ResponseCode.ILLEGAL_REGIST);
			}
			
		} catch(Exception e) {
			// 非法注册
			return new CommonResult<>(ResponseCode.ILLEGAL_REGIST);
		}
		// 校验验证码
		if(!((String)session.getAttribute("verifyCode")).equalsIgnoreCase(verifyCode)) {
			// 非法注册
			return new CommonResult<>(ResponseCode.ILLEGAL_REGIST);
		}
		// sno，pwd非空判断
		if(sno == null || sno.trim().length() == 0 || pwd == null || pwd.trim().length() != 32) {
			// 非法注册
			return new CommonResult<>(ResponseCode.ILLEGAL_REGIST);
		}
		if(!sno.matches("^[1-9]\\d{12}$")) {
			// 非法注册
			return new CommonResult<>(ResponseCode.ILLEGAL_REGIST);
		}
		// 开始注册
		User user = new User();
		//  设置学号
		user.setSno(new Long(sno));
		// 设置密码
		user.setPwd(pwd);
		// 设置联系电话
		user.setPhoneNumber("");
		// 设置默认昵称
		user.setNickname("用户" + CommonUtils.uuid());
		// 设置院系
		user.setDepartment("");
		// 设置默认图片路径
		user.setImgPath(DEFAULT_IMG_PATH);
		// 设置账号状态
		user.setState(0);
		// 设置注册时间
		user.setRegistTime(new Date());
		ResponseCode responseCode = userService.regist(user);
		return new CommonResult<>(responseCode);
	}
	
	/**
	 * 	学号登录
	 * 	sno：学号，必传
	 * 	pwd：密码（已经过MD5加密），必传
	 * 	phone：校验字段，此字段应为""，若不为空则认为是恶意登录，必传
	 * 
	 */
	@ResponseBody
	@RequestMapping(value = "/loginBySno", method = RequestMethod.POST)
	public Object loginBySno(@RequestParam String sno, 
			@RequestParam String pwd,
			@RequestParam String phone, 
			HttpServletResponse response,
			HttpSession session) {
		
		// 校验字段
		if(phone != null && phone.length() > 0) {
			// 非法登录
			return new CommonResult<>(ResponseCode.ILLEGAL_LOGIN);
		}
		// sno，pwd非空判断
		if(sno == null || sno.trim().length() == 0 || pwd == null || pwd.trim().length() == 0) {
			// 非法登录
			return new CommonResult<>(ResponseCode.ILLEGAL_LOGIN);
		}
		if(!sno.matches("^[1-9]\\d{12}$")) {
			// 非法登录
			return new CommonResult<>(ResponseCode.ILLEGAL_LOGIN);
		}
		User user = new User();
		user.setSno(new Long(sno));
		user.setPwd(pwd);
		CommonResult<User> result = userService.loginBySno(user);
		int code = result.getCode();
		if(code == 200) {
			// 登录成功，向Cookie中保存用户名和密码
			CommonUtils.setLoginCookie(sno + Info.USER_COOKIE_SEPARATOR + pwd, response, Info.USER_COOKIE);
			// 在session中保存用户的登录状态
			session.setAttribute(Info.USER_SESSION, result.getData());
		}
		return result;
	}
	
	/**
	 * 	判断用户是否已经登录
	 * 	sno：Cookie中的学号，必传
	 * 	pwd：Cookie中的密码，必传
	 * */
	@ResponseBody
	@RequestMapping(value = "/isLogin", method = RequestMethod.POST)
	public Object isLogin(@RequestParam String sno, 
			@RequestParam String pwd, 
			HttpSession session,
			HttpServletResponse response,
			HttpServletRequest request) {
		// sno，pwd非空判断
		if(sno == null || sno.trim().length() == 0 || pwd == null || pwd.trim().length() == 0) {
			// 非法登录
			return new CommonResult<>(ResponseCode.ILLEGAL_LOGIN);
		}
		if(!sno.matches("^[1-9]\\d{12}$")) {
			// 非法登录
			return new CommonResult<>(ResponseCode.ILLEGAL_LOGIN);
		}
		User userSession = (User)session.getAttribute(Info.USER_SESSION);
		// 若session已存储该用户信息则证明该用户已登录
		if(userSession != null) {
			// 向原来的Cookie中保存用户名和密码（覆盖掉原来的信息）
			CommonUtils.setLoginCookie(sno + Info.USER_COOKIE_SEPARATOR + pwd, response, Info.USER_COOKIE);
			// 不更新用户的最后登录时间
			// 更新session里面的用户信息
			userSession = userService.findUser(userSession.getUid());
			session.setAttribute(Info.USER_SESSION, userSession);
			return new CommonResult<>(ResponseCode.SUCCESS, userSession);
		} else {
			// session中找不到则查询数据库sno和password是否正确
			User user = new User();
			user.setSno(new Long(sno));
			user.setPwd(pwd);
			CommonResult<User> result = userService.loginByCookie(user);
			int code = result.getCode();
			if(code == 200) {
				// 登录成功
				// 向原来的Cookie中保存用户名和密码（覆盖掉原来的信息）
				CommonUtils.setLoginCookie(sno + Info.USER_COOKIE_SEPARATOR + pwd, response, Info.USER_COOKIE);
				// 在session中保存用户的登录状态
				session.setAttribute(Info.USER_SESSION, result.getData());
			}
			return result;
		}
		
	}
	
	/**
	 * 	用户注销
	 * 	redirectULRL：注销后转发路径
	 * 
	 * */
	@RequestMapping("/logout")
	public String logout(String redirectURL,
			HttpSession session,
			HttpServletRequest request,
			HttpServletResponse response) {
		
		session.removeAttribute(Info.USER_SESSION);
		session.invalidate();
		removeCookie(request.getCookies(), Info.USER_COOKIE, response);
//		if("http://127.0.0.1:8080/qb".equals(redirectURL)) {
//			return "redirect: http://127.0.0.1:8080/qb";
//		}
//		// 若redirectURL不是首页地址，则都转发到登录页面
//		return "redirect: http://127.0.0.1:8080/qb/page/user/login.html";
		return "redirect:" + redirectURL;
	}
	
	/**
	 * 	修改个人信息
	 * 	nickname：昵称，必传
	 * 	phoneNumber：手机号，必传
	 * 	qno：QQ号，必传
	 * 	classname：班级，必传
	 * 	dormitory：寝室号，必传
	 * 	department：院系，必传
	 * @throws UnsupportedEncodingException
	 * 
	 * */
	@ResponseBody
	@RequestMapping(value = "/modifyInfo", method = RequestMethod.POST)
	public Object modifyUserInfo(@RequestParam String nickname,
			@RequestParam String phoneNumber,
			@RequestParam String qno,
			@RequestParam String classname,
			@RequestParam String dormitory,
			@RequestParam String department,
			HttpSession session, 
			HttpServletRequest request,
			HttpServletResponse response) throws UnsupportedEncodingException {
		
		// 处理session和cookie过期问题
		int i = CommonUtils.handleSCExpire(request.getCookies(), session, response, userService); 
		if(i == 0) {
			return new CommonResult<>(ResponseCode.UNLOGIN);
		}
		nickname = URLDecoder.decode(URLEncoder.encode(nickname, "UTF-8"),"UTF-8");
		classname = URLDecoder.decode(URLEncoder.encode(classname, "UTF-8"),"UTF-8");
		dormitory = URLDecoder.decode(URLEncoder.encode(dormitory, "UTF-8"),"UTF-8");
		
		// 校验格式
		boolean flag = true;
		List<String> departmentList = Arrays.asList(new String[] {
				"经济管理分院",
				"理工分院",
				"艺术与传媒分院",
				"护理分院",
				"外国语分院",
				"体育分院",
				"文法分院",
				"继续教育学院",
				"马克思主义学院",
				"老师"
		});
		if (nickname == null || "".equals(nickname.trim()) || nickname.length() > 50) {
			// 昵称为空或前后有空格或长度大于50
			flag = false;
		} else if(!phoneNumber.matches("^1[345678]\\d{9}$")) {
			// 电话格式不匹配
			flag = false;
		} else if(!departmentList.contains(department)) {
			// 院系不正确
			flag = false;
		} else if(!"".equals(qno) && !qno.matches("^[1-9]\\d{4,9}$")) {
			// QQ号格式不正确
			flag = false;
		} else if(!"".equals(classname) && classname.length() > 30) {
			// 班级长度大于30
			flag = false;
		} else if(!"".equals(dormitory) && dormitory.length() > 30) {
			// 寝室号长度大于30
			flag = false;
		}
		if(!flag) {
			// 格式不正确
			return new CommonResult<>(ResponseCode.INCORECT_FORMAT);
		}
		User user = new User();
		// 添加手机号
		user.setPhoneNumber(phoneNumber);
		// 添加QQ号
		user.setQno(qno);
		// 去除classname前后的空格
		user.setClassname(classname.trim());
		// 去除dormitory前后的空格
		user.setDormitory(dormitory.trim());
		// 添加department
		user.setDepartment(department.trim());
		// 添加nickname
		user.setNickname(nickname.trim());
		// 添加uid
		user.setUid(((User)session.getAttribute(Info.USER_SESSION)).getUid());
		userService.modifyUserInfo(user);
		// 更新session里面的用户信息
		session.setAttribute(Info.USER_SESSION, userService.findUser(user.getUid()));
		return new CommonResult<>(ResponseCode.SUCCESS);
	}
	
	/**
	 * 	用户上传头像
	 * 	file：上传的图片name
	 * @throws IOException 
	 * @throws IllegalStateException 
	 * 
	 * */
	@RequestMapping(value = "/headPortrait", method = RequestMethod.POST)
	public String uploadHeadPortrait(@RequestParam MultipartFile file,
			HttpSession session,
			HttpServletRequest request,
			HttpServletResponse response) throws IllegalStateException, IOException {
		boolean flag = true;
		long size = file.getSize();
		List<String> list = Arrays.asList(new String[] {
				".JPG",
				".PNG"
		});
		if(size > 1024 * 1024 * 2) {
			flag = false;
		} 
		String filename = file.getOriginalFilename();
		String fileFormat = filename.substring(filename.lastIndexOf('.'));
		if(!list.contains(fileFormat.toUpperCase())) {
			flag = false;
		}
		
		if(!flag) {
			return "redirect:/page/user/space?e";
		} else {
			// 处理session和Cookie过期问题
			int i = CommonUtils.handleSCExpire(request.getCookies(), session, response, userService); 
			if(i == 0) {
				return "redirect:/page/user/login.html";
			}
			// 开始上传用户头像
			String realPath = session.getServletContext().getRealPath("").replaceAll("\\\\", "/");
			if(realPath.endsWith("/")) {
				realPath = realPath.substring(0, realPath.length() - 1);
			}
			File dir = new File(realPath , "/images/face");
			File[] files = dir.listFiles();
			String newDirPath = null;
			// 若face文件夹下没有创建过文件夹，即只有一张默认头像图片
			if(files == null || files.length == 1) {
				newDirPath = dir.getAbsolutePath().replaceAll("\\\\", "/") + "/1/";
				new File(newDirPath).mkdir();
			} else {
				for(File f : files) {
					if(f.isDirectory()) {
						File[] _files = f.listFiles();
						if(_files != null && _files.length < Info.MAX_IMG_COUNT) {
							newDirPath = f.getAbsolutePath().replaceAll("\\\\", "/") + "/";
							break;
						}
					}
				}
				if(newDirPath == null) {
					newDirPath = dir.getAbsolutePath().replaceAll("\\\\", "/") + "/" + files.length + "/";
					new File(newDirPath).mkdir();
				}
			}
			String path = newDirPath + CommonUtils.uuid() + fileFormat;
			file.transferTo(new File(path));
			User userSession = (User)session.getAttribute(Info.USER_SESSION);
			User user = new User();
			user.setUid(userSession.getUid());
			user.setImgPath("/qb" + path.substring(realPath.length()));
			userService.modifyUserInfo(user);
			// 更新session域中的User
			session.setAttribute(Info.USER_SESSION, userService.findUser(userSession.getUid()));
			return "redirect:/page/user/space?s";
		}
	}
	
	/**
	 * List集合转String，不能用Arrays.toString(list.toArray())，因为这个方式返回的字符串带中括号，逗号和空格
	 * list：需要转换的List
	 * TODO 使用CommonUtils
	 * 
	 */
	private String listToString(List list) {
		Object[] arr = list.toArray();
		String str = "";
		for(int i = 0; i < arr.length; i++) {
			str = str + arr[i];
		}
		return str;
	}
	
	/**
	 * 	根据key销毁Cookie
	 * 	cookies：cookies
	 * 	key：键
	 * 
	 * */
    private void removeCookie(Cookie[] cookies, String key, HttpServletResponse response) {
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(key)) {
                	cookie.setMaxAge(0);
                    cookie.setPath("/"); // 必须设置，若设置了domain，则清除cookie时也要设置domain  
            		response.addCookie(cookie);
            		break;
                }
            }
        }
    }
}
